#include <stdio.h>
#include <string.h>
#include "../../src/ser.h"
#include "../../src/conexion.h"
#include "../../src/utils.h"

#define FIRMA "..Vericado.SERVER.0AF600D4.."
#define MENSAJE_DESCONEXION "EL SERVIDOR NO ADMITE MAS PEDIDOS"
#define MAX_RESPUESTAS_ACEPTADAS 25
#define MS_ENTRE_PROCESAMIENTOS 100

typedef char* (*t_generar_respuesta)(char*);
typedef struct { 
	t_generar_respuesta generar_respuesta;
	char* texto_impresion;
	size_t respuestas_pendientes;
} t_objeto_servidor;


void imprimir(int cliente, int codigo, void *data, int size, void *objeto){
	t_objeto_servidor* obj_servidor = (t_objeto_servidor*)objeto;
	if(codigo == CON_DATOS_RECIBIDOS) {
		printf("SERVER Mensaje de texto recibido. Cliente: %d. Texto: '%s'.\n", cliente, (char*)data);
		printf("%s\n", obj_servidor->texto_impresion);
	}
}

void echo(int cliente, int codigo, void *data, int size, void *objeto){
	t_objeto_servidor* obj_servidor = (t_objeto_servidor*)objeto;
	if(codigo == CON_DATOS_RECIBIDOS) {
		if (obj_servidor->respuestas_pendientes == 0) {
			printf("SERVER desconectando cliente '%d' por respuestas totales recibidas\n", cliente);
			ser_enviar(cliente, MENSAJE_DESCONEXION, strlen(MENSAJE_DESCONEXION) + 1);
			ser_desconectar(cliente);
		}
		else {
			char* respuesta = obj_servidor->generar_respuesta((char*)data);
			printf("SERVER Enviando respuesta: '%s'.\n", respuesta);
			ser_enviar(cliente, respuesta, strlen(respuesta) + 1);
			free(respuesta);
			obj_servidor->respuestas_pendientes--;	
		}
	}
}

char* agregar_firma_servidor(char* mensaje) {
	char* respuesta = (char*)malloc(strlen(mensaje) + strlen(FIRMA) + 1);
	strcpy(respuesta, mensaje);
	strcat(respuesta, FIRMA);
	return respuesta;
}

int main(int argc, char* argv[]) {
	if (argc != 2) {
		printf("Cantidad de argumentos inválida. Formato de ejecucion: ./server <puerto>\n");
		return 1;
	}
	else {
		int puerto = atoi(argv[1]);
		t_objeto_servidor obj_servidor;
		obj_servidor.generar_respuesta = agregar_firma_servidor;
		obj_servidor.texto_impresion = "============================";
		obj_servidor.respuestas_pendientes = MAX_RESPUESTAS_ACEPTADAS;
		
		printf("SERVER Iniciando servidor. Presione 'q' para salir...\n");
		ser_suscribir(echo, &obj_servidor);
		ser_suscribir(imprimir, &obj_servidor);

		ser_iniciar(puerto);
		char caracter_teclado = '\0';
		while (caracter_teclado != 'q') {
			ser_procesar();
			caracter_teclado = utils_getchar_nonblocking();
			if (caracter_teclado != 'q')
				utils_mssleep(MS_ENTRE_PROCESAMIENTOS);
		}
			
    ser_dessuscribir(&obj_servidor);
	ser_terminar();
    return 0;
  }
}
